#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include "posixfifo.h"


int pipe_file_check(char* pipe_file_name)
{
	int res = 0;
	//检查文件是否存在, 如果不存在则创建新管道文件
	if(access(pipe_file_name, F_OK) == -1)
	{
		fprintf(stderr, "FIFO file don't exsit, create new [%s] ", pipe_file_name);
		if( (res=mkfifo(pipe_file_name, 0777)) != 0 )
		{
			fprintf(stderr, "error, mkfifo:%s\n", strerror(errno));
			return 1;
		}
		else
		{
			fprintf(stderr, "success.\n");
			return 0;
		}
	}
	else
	{
		fprintf(stderr, "FIFO file [%s] found.\n", pipe_file_name);
		return 0;
	}
}

int pipe_file_open(char* pipe_file_name)
{
	int fd;
	fd = open(pipe_file_name, O_RDWR);
	if(fd != -1)
	{
		fprintf(stderr, "FIFO file open success.\n");
		return fd;
	}
	else{
		fprintf(stderr, "FIFO file open failed.\n");
		return -1;
	}
}

int pipe_file_read(struct __fifo_pipe_control_block* fpcb)
{
	//int buflen = 0;
	fpcb->pbuflen = 0;
	memset(fpcb->pbuffer, 0, FIFO_BUF_SIZE);
	fpcb->pbuflen = read(fpcb->fd, fpcb->pbuffer, fpcb->pbufsz);
	//printf("%s\n", fpcb->pbuffer);
	//fprintf(stderr, "fifo pipe has %d bytes\n", buflen);
	//return buflen;
	return fpcb->pbuflen;
}

#define LINE_MAX_SIZE 4096
void pfbuffer_to_arrays_by_line(struct __fifo_pipe_control_block* fpcb)
{
	int c;
	int ln, j;
	ln = 0; j = 0;

	char temp_buf[LINE_MAX_SIZE];
	fpcb->arrays = (unsigned char**)malloc(sizeof(unsigned char*));
	unsigned char** new_arrays;

	for(c = 0; c < fpcb->pbuflen; c++)
	{
		if(fpcb->pbuffer[c] == '\n')
		{
			temp_buf[j] = '\0';
			//line字符串存储空间, +1 Byte存放结束符 '\0'
			fpcb->arrays[ln] = (unsigned char*)malloc( (j + 1) * sizeof(unsigned char));
			strcpy(fpcb->arrays[ln], temp_buf);
			//计数值更新
			ln++; j = 0;
			//函数信息 行数更新
			fpcb->lines = ln;
			//增加1个字符串存储空间
			new_arrays = (unsigned char**)realloc(fpcb->arrays,
											 (1 + fpcb->lines) * sizeof(unsigned char*) );
			if(new_arrays != NULL)
			{
				fpcb->arrays = new_arrays;
			}else{
				fprintf(stderr, "SYS/> {ERROR} fifo lines' arrarys realloc failed!\n");
			}
		}
		else
		{
			temp_buf[j] = fpcb->pbuffer[c];
			j++;
		}
	}
}

void print_arrays(struct __fifo_pipe_control_block* fpcb)
{
	int i;
	for(i = 0; i < fpcb->lines; i++)
		printf("LN%d -> %s\n", i+1, fpcb->arrays[i]);
}

void fpcb_construct(char* pipe_file_name, struct __fifo_pipe_control_block* fpcb)
{
	strcpy(fpcb->pf, pipe_file_name);
	memset(fpcb->pbuffer, 0, FIFO_BUF_SIZE);
	fpcb->pbufsz = FIFO_BUF_SIZE;
	fpcb->pbuflen = 0;
	if(pipe_file_check(pipe_file_name) == 0)
	{
		fpcb->fd = pipe_file_open(pipe_file_name);
	}

	fpcb->pfarray = pfbuffer_to_arrays_by_line;
	fpcb->arrprint = print_arrays;
	fpcb->pfread = pipe_file_read;
}

void fpcb_release(struct __fifo_pipe_control_block* fpcb)
{
	int i;
	for(i = 0; i < fpcb->lines; i++)
	{
		if(fpcb->arrays[i] != NULL);
		{
			free(fpcb->arrays[i]);
		}
	}

	if(fpcb->arrays != NULL)
		free(fpcb->arrays);
	
	/*
	 * 管道文件描述符返回给系统
	 */
	if(fpcb->fd > 0)
		close(fpcb->fd);
}

